"""
数据验证工具模块
提供各种数据验证功能，包括用户输入、业务数据等
"""

import re
import email.utils
from typing import Any, Dict, List, Optional, Tuple, Union
from core.utils.logger import warning, error, debug
from core.utils.error_handler import ValidationError


class BaseValidator:
    """基础验证器类"""
    
    @staticmethod
    def validate_not_empty(value: Any, field_name: str) -> Tuple[bool, str]:
        """验证值不为空"""
        if value is None or value == "" or (isinstance(value, str) and value.strip() == ""):
            return False, f"{field_name} cannot be empty"
        return True, ""
    
    @staticmethod
    def validate_length(value: str, field_name: str, min_length: int = 1, max_length: int = None) -> Tuple[bool, str]:
        """验证字符串长度"""
        if not isinstance(value, str):
            return False, f"{field_name} must be a string"
        
        if len(value) < min_length:
            return False, f"{field_name} cannot be shorter than {min_length} characters"
        
        if max_length and len(value) > max_length:
            return False, f"{field_name} cannot be longer than {max_length} characters"
        
        return True, ""
    
    @staticmethod
    def validate_regex(value: str, field_name: str, pattern: str, error_message: str) -> Tuple[bool, str]:
        """验证正则表达式"""
        if not isinstance(value, str):
            return False, f"{field_name} must be a string"
        
        if not re.match(pattern, value):
            return False, error_message
        
        return True, ""


class UserValidator(BaseValidator):
    """用户数据验证器"""
    
    @staticmethod
    def validate_username(username: str) -> Tuple[bool, str]:
        """验证用户名"""
        # 检查是否为空
        is_valid, error_msg = BaseValidator.validate_not_empty(username, "Username")
        if not is_valid:
            return False, error_msg
        
        # 检查长度
        is_valid, error_msg = BaseValidator.validate_length(username, "Username", 3, 20)
        if not is_valid:
            return False, error_msg
        
        # 检查字符（只允许字母、数字、下划线）
        is_valid, error_msg = BaseValidator.validate_regex(
            username, "Username", r'^[a-zA-Z0-9_]+$', 
            "Username can only contain letters, numbers and underscores"
        )
        if not is_valid:
            return False, error_msg
        
        # 检查不能以数字开头
        if username[0].isdigit():
            return False, "Username cannot start with a number"
        
        return True, ""
    
    @staticmethod
    def validate_email(email: str) -> Tuple[bool, str]:
        """验证邮箱地址"""
        # 检查是否为空
        is_valid, error_msg = BaseValidator.validate_not_empty(email, "Email")
        if not is_valid:
            return False, error_msg
        
        # 检查长度
        is_valid, error_msg = BaseValidator.validate_length(email, "Email", 5, 100)
        if not is_valid:
            return False, error_msg
        
        # 使用正则表达式验证邮箱格式
        email_pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
        is_valid, error_msg = BaseValidator.validate_regex(
            email, "Email", email_pattern, "Email format is incorrect"
        )
        if not is_valid:
            return False, error_msg
        
        return True, ""
    
    @staticmethod
    def validate_password(password: str) -> Tuple[bool, str]:
        """验证密码强度"""
        # 检查是否为空
        is_valid, error_msg = BaseValidator.validate_not_empty(password, "Password")
        if not is_valid:
            return False, error_msg
        
        # 检查长度
        if len(password) < 8:
            return False, "Password must be at least 8 characters long"
        
        if len(password) > 128:
            return False, "Password cannot exceed 128 characters"
        
        # 检查是否包含字母
        if not re.search(r'[a-zA-Z]', password):
            return False, "Password must contain at least one letter"
        
        # 检查是否包含数字
        if not re.search(r'\d', password):
            return False, "Password must contain at least one digit"
        
        # 检查是否包含特殊字符
        if not re.search(r'[!@#$%^&*(),.?":{}|<>]', password):
            return False, "Password must contain at least one special character"
        
        # 检查常见弱密码
        weak_passwords = [
            'password', '123456', '12345678', 'qwerty', 'abc123',
            'password123', 'admin', 'letmein', 'welcome', 'monkey'
        ]
        if password.lower() in weak_passwords:
            return False, "Password is too simple, please use a more complex password"
        
        return True, ""
    
    @staticmethod
    def validate_role(role: str) -> Tuple[bool, str]:
        """验证用户角色"""
        valid_roles = ['customer', 'seller', 'admin']
        if role not in valid_roles:
            return False, f"User role must be one of: {', '.join(valid_roles)}"
        return True, ""


class ProductValidator(BaseValidator):
    """商品数据验证器"""
    
    @staticmethod
    def validate_name(name: str) -> Tuple[bool, str]:
        """验证商品名称"""
        # 检查是否为空
        is_valid, error_msg = BaseValidator.validate_not_empty(name, "Product name")
        if not is_valid:
            return False, error_msg
        
        # 检查长度
        is_valid, error_msg = BaseValidator.validate_length(name, "Product name", 1, 100)
        if not is_valid:
            return False, error_msg
        
        return True, ""
    
    @staticmethod
    def validate_price(price: Union[int, float, str]) -> Tuple[bool, str]:
        """验证商品价格"""
        try:
            price_float = float(price)
            if price_float < 0:
                return False, "Product price cannot be negative"
            if price_float > 999999.99:
                return False, "Product price cannot exceed 999999.99"
            return True, ""
        except (ValueError, TypeError):
            return False, "Product price must be a valid number"
    
    @staticmethod
    def validate_stock(stock: Union[int, str]) -> Tuple[bool, str]:
        """验证库存数量"""
        try:
            stock_int = int(stock)
            if stock_int < 0:
                return False, "Stock quantity cannot be negative"
            if stock_int > 999999:
                return False, "Stock quantity cannot exceed 999999"
            return True, ""
        except (ValueError, TypeError):
            return False, "Stock quantity must be a valid integer"
    
    @staticmethod
    def validate_category(category: str) -> Tuple[bool, str]:
        """验证商品分类"""
        # 检查是否为空
        is_valid, error_msg = BaseValidator.validate_not_empty(category, "Product category")
        if not is_valid:
            return False, error_msg
        
        # 检查长度
        is_valid, error_msg = BaseValidator.validate_length(category, "Product category", 1, 50)
        if not is_valid:
            return False, error_msg
        
        return True, ""
    
    @staticmethod
    def validate_description(description: str) -> Tuple[bool, str]:
        """验证商品描述"""
        if not description:
            return True, ""  # 描述可以为空
        
        # 检查长度
        is_valid, error_msg = BaseValidator.validate_length(description, "Product description", 0, 1000)
        if not is_valid:
            return False, error_msg
        
        return True, ""


class OrderValidator(BaseValidator):
    """订单数据验证器"""
    
    @staticmethod
    def validate_quantity(quantity: Union[int, str]) -> Tuple[bool, str]:
        """验证商品数量"""
        try:
            qty_int = int(quantity)
            if qty_int <= 0:
                return False, "Product quantity must be greater than 0"
            if qty_int > 999:
                return False, "Product quantity cannot exceed 999"
            return True, ""
        except (ValueError, TypeError):
            return False, "Product quantity must be a valid integer"
    
    @staticmethod
    def validate_order_total(total: Union[int, float, str]) -> Tuple[bool, str]:
        """验证订单总金额"""
        try:
            total_float = float(total)
            if total_float < 0:
                return False, "Order total cannot be negative"
            if total_float > 999999.99:
                return False, "Order total cannot exceed 999999.99"
            return True, ""
        except (ValueError, TypeError):
            return False, "Order total must be a valid number"


class DataValidator:
    """数据验证器主类"""
    
    def __init__(self):
        self.user_validator = UserValidator()
        self.product_validator = ProductValidator()
        self.order_validator = OrderValidator()
    
    def validate_user_data(self, user_data: Dict[str, Any]) -> Tuple[bool, List[str]]:
        """验证用户数据"""
        errors = []
        
        # 验证用户名
        if 'username' in user_data:
            is_valid, error_msg = self.user_validator.validate_username(user_data['username'])
            if not is_valid:
                errors.append(error_msg)
        
        # 验证邮箱
        if 'email' in user_data:
            is_valid, error_msg = self.user_validator.validate_email(user_data['email'])
            if not is_valid:
                errors.append(error_msg)
        
        # 验证密码
        if 'password' in user_data:
            is_valid, error_msg = self.user_validator.validate_password(user_data['password'])
            if not is_valid:
                errors.append(error_msg)
        
        # 验证角色
        if 'role' in user_data:
            is_valid, error_msg = self.user_validator.validate_role(user_data['role'])
            if not is_valid:
                errors.append(error_msg)
        
        return len(errors) == 0, errors
    
    def validate_product_data(self, product_data: Dict[str, Any]) -> Tuple[bool, List[str]]:
        """验证商品数据"""
        errors = []
        
        # 验证商品名称
        if 'name' in product_data:
            is_valid, error_msg = self.product_validator.validate_name(product_data['name'])
            if not is_valid:
                errors.append(error_msg)
        
        # 验证价格
        if 'price' in product_data:
            is_valid, error_msg = self.product_validator.validate_price(product_data['price'])
            if not is_valid:
                errors.append(error_msg)
        
        # 验证库存
        if 'stock' in product_data:
            is_valid, error_msg = self.product_validator.validate_stock(product_data['stock'])
            if not is_valid:
                errors.append(error_msg)
        
        # 验证分类
        if 'category' in product_data:
            is_valid, error_msg = self.product_validator.validate_category(product_data['category'])
            if not is_valid:
                errors.append(error_msg)
        
        # 验证描述
        if 'description' in product_data:
            is_valid, error_msg = self.product_validator.validate_description(product_data['description'])
            if not is_valid:
                errors.append(error_msg)
        
        return len(errors) == 0, errors
    
    def validate_order_data(self, order_data: Dict[str, Any]) -> Tuple[bool, List[str]]:
        """验证订单数据"""
        errors = []
        
        # 验证订单项
        if 'items' in order_data and isinstance(order_data['items'], list):
            for i, item in enumerate(order_data['items']):
                if 'quantity' in item:
                    is_valid, error_msg = self.order_validator.validate_quantity(item['quantity'])
                    if not is_valid:
                        errors.append(f"Order item {i+1}: {error_msg}")
        
        # 验证总金额
        if 'total' in order_data:
            is_valid, error_msg = self.order_validator.validate_order_total(order_data['total'])
            if not is_valid:
                errors.append(error_msg)
        
        return len(errors) == 0, errors
    
    def validate_cart_item(self, product_id: str, quantity: int) -> Tuple[bool, List[str]]:
        """验证购物车商品"""
        errors = []
        
        # 验证商品ID
        if not product_id or not isinstance(product_id, str):
            errors.append("Product ID cannot be empty")
        
        # 验证数量
        is_valid, error_msg = self.order_validator.validate_quantity(quantity)
        if not is_valid:
            errors.append(error_msg)
        
        return len(errors) == 0, errors


# 全局验证器实例
validator = DataValidator()


# 便捷函数
def validate_user(user_data: Dict[str, Any]) -> Tuple[bool, List[str]]:
    """验证用户数据"""
    return validator.validate_user_data(user_data)


def validate_product(product_data: Dict[str, Any]) -> Tuple[bool, List[str]]:
    """验证商品数据"""
    return validator.validate_product_data(product_data)


def validate_order(order_data: Dict[str, Any]) -> Tuple[bool, List[str]]:
    """验证订单数据"""
    return validator.validate_order_data(order_data)


def validate_cart_item(product_id: str, quantity: int) -> Tuple[bool, List[str]]:
    """验证购物车商品"""
    return validator.validate_cart_item(product_id, quantity)
